﻿using System.Collections.Generic;

namespace GameStructure.Types
{
    public class Text
    {
        private readonly Font _font;
        private readonly List<CharacterSprite> _bitmapText = new List<CharacterSprite>();
        private readonly string _text;
        private Color _color = new Color(1, 1, 1, 1);
        private Vector _dimensions;
        private readonly int _maxWidth = -1;

        public double Width
        {
            get { return _dimensions.X; }
        }

        public double Height
        {
            get { return _dimensions.Y; }
        }

        public IEnumerable<CharacterSprite> CharacterSprites
        {
            get { return _bitmapText; }
        }

        public Text(string text, Font font, int maxWidth = -1)
        {
            _text = text;
            _font = font;
            _maxWidth = maxWidth;
            CreateText(0, 0, _maxWidth);
        }

        public void SetPosition(double x, double y)
        {
            CreateText(x, y);
        }

        public void SetColor()
        {
            foreach (var s in _bitmapText)
            {
                s.Sprite.SetColor(_color);
            }
        }

        public void SetColor(Color color)
        {
            _color = color;
            foreach (var s in _bitmapText)
            {
                s.Sprite.SetColor(color);
            }
        }

        private void CreateText(double x, double y)
        {
            CreateText(x, y, _maxWidth);
        }

        private void CreateText(double x, double y, double maxWidth)
        {
            _bitmapText.Clear();
            var currentX = x;
            var currentY = y;

            var words = _text.Split(' ');

            foreach (var word in words)
            {
                var nextWordLength = _font.MeasureFont(word);

                if (maxWidth != -1 && (currentX + nextWordLength.X) > maxWidth)
                {
                    currentX = 0;
                    currentY += nextWordLength.Y;
                }

                var wordWithSpace = word + " "; // add the space character that was removed.

                // Kerning should go here, use char previousCharacter = nil
                foreach (var c in wordWithSpace)
                {
                    var sprite = _font.CreateSprite(c);
                    var xOffset = ((float)sprite.Data.XOffset) / 2;
                    var yOffset = (sprite.Data.Height * 0.5f) + sprite.Data.YOffset;
                    sprite.Sprite.SetPosition(currentX + xOffset, y - currentY - yOffset);
                    currentX += sprite.Data.XAdvance;
                    _bitmapText.Add(sprite);
                }
            }

            _dimensions = _font.MeasureFont(_text, _maxWidth);
            _dimensions.Y = currentY;
            SetColor(_color);
        }
    }
}
